package com

import com.boge.utils.SystemUtils
import java.awt.*
import java.awt.event.ActionEvent
import java.awt.event.MouseAdapter
import java.awt.event.MouseEvent
import java.io.InputStream
import java.nio.file.*
import java.time.LocalDateTime
import javax.imageio.ImageIO
import javax.swing.*
import kotlin.io.path.*
import kotlin.system.exitProcess


class Main {

    private lateinit var startupItem: JMenuItem
    val startup = Path(SystemUtils.home, "AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup")

    private val disMode by lazy {
        GraphicsEnvironment.getLocalGraphicsEnvironment().defaultScreenDevice.displayMode
    }

    val screenX by lazy {
        Toolkit.getDefaultToolkit().screenSize.width.toDouble() / disMode.width
    }
    val screenY by lazy {
        Toolkit.getDefaultToolkit().screenSize.height.toDouble() / disMode.height
    }

    companion object {
        var trayIcon: TrayIcon? = null
    }

    init {
        createTray()
    }

    fun start() {
        logger.info("jarRunPath: ${SystemUtils.jarRunPath}")
        logger.info("home: ${SystemUtils.home}")
        logger.info("dir: ${SystemUtils.dir}")
        logger.info("runPath: ${SystemUtils.runPath}")
        logger.info("启动 ${LocalDateTime.now()} ")

        WatchFileService.init()

    }

    fun createTray() {
        if (SystemTray.isSupported()) {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName())

            val imageStream = Main::class.java.getResourceAsStream("/toolkit.png")
            val image = ImageIO.read(imageStream)
            val systemTray = SystemTray.getSystemTray()

            trayIcon = TrayIcon(image, "文件监控系统")
            trayIcon?.isImageAutoSize = true

            //使用JDialog 作为JPopupMenu载体
            val jDialog = JDialog()
            //关闭JDialog的装饰器
            jDialog.isUndecorated = true
            //jDialog作为JPopupMenu载体不需要多大的size
            jDialog.setSize(1, 1)

            //创建JPopupMenu
            //重写firePopupMenuWillBecomeInvisible
            //消失后将绑定的组件一起消失
            val jPopupMenu = object : JPopupMenu() {
                public override fun firePopupMenuWillBecomeInvisible() {
                    // JPopupMenu不可见时绑定载体组件jDialog也不可见
                    jDialog.isVisible = false
                }
            }
            jPopupMenu.setSize(100, 30)


            jPopupMenu.add(createMenuItem("打开Info日志") {
                SystemUtils.runPath.resolve("data/logs/info.log").let {
                    if (it.exists()) {
                        Desktop.getDesktop().open(it.toFile())
                    } else alert("日志不存在 $it")
                }
            })
            jPopupMenu.add(createMenuItem("打开Debug日志") {
                SystemUtils.runPath.resolve("data/logs/debug.log").let {
                    if (it.exists()) {
                        Desktop.getDesktop().open(it.toFile())
                    } else alert("日志不存在 $it")
                }
            })
            jPopupMenu.add(createMenuItem("打开Error日志") {
                SystemUtils.runPath.resolve("data/logs/error.log").let {
                    if (it.exists()) {
                        Desktop.getDesktop().open(it.toFile())
                    } else alert("日志不存在 $it")
                }
            })
            jPopupMenu.addSeparator()
            jPopupMenu.add(createMenuItem("打开配置文件") {
                Desktop.getDesktop().open(SystemUtils.runPath.resolve("data.json").toFile())
            })
            jPopupMenu.add(createMenuItem("打开所在目录") {
                Desktop.getDesktop().open(SystemUtils.runPath.toFile())
            })
            jPopupMenu.add(createMenuItem("从新加载配置") {
                WatchFileService.rebootWatch()
            })
            jPopupMenu.add(createMenuItem("重启") {
                exitProcess(1)
            })
            jPopupMenu.addSeparator()
            //添加菜单选项
            jPopupMenu.add(createMenuItem("") {
                when (it.actionCommand) {
                    "Enable" -> addStartup()
                    "Disable" -> removeStartup()
                }
            }.also {
                startupItem = it
            })
            this.updateStartup()
            jPopupMenu.addSeparator()
            jPopupMenu.add(createMenuItem("退出") {
                exitProcess(0)
            })

            trayIcon?.addMouseListener(object : MouseAdapter() {
                override fun mouseReleased(e: MouseEvent?) {
                    super.mouseReleased(e)
                    //左键点击
                    if (e?.button == 1) {
                        logger.debug("点击托盘图标")
                    } else if (SwingUtilities.isRightMouseButton(e) && e!!.isPopupTrigger) {
                        logger.debug("右键点击托盘图标")
                        jDialog.setLocation((e.x * screenX).toInt(), (e.y * screenY).toInt() - jPopupMenu.height - 5)
                        // 显示载体
                        jDialog.isVisible = true
                        // 在载体的0,0处显示对话框
                        jPopupMenu.selectionModel.clearSelection()
                        jPopupMenu.show(jDialog, 0, 0)
                    }
                }
            })

            // 设置托盘图标的点击事件
            trayIcon?.addActionListener {
                println("点我了")
            }
            // 添加到系统托盘
            systemTray.add(trayIcon)
        }
    }

    private fun createMenuItem(label: String, action: (actionEvent: ActionEvent) -> Unit): JMenuItem {
        val item = JMenuItem(label)
//        item.font = Font(null, Font.BOLD, 14)
        item.addActionListener {
            action.invoke(it)
        }
        return item
    }

    private fun updateStartup() {
        val startupPath = startup.resolve("${Path(SystemUtils.jarRunPath).nameWithoutExtension}.lnk")
        logger.info("检查开机启动文件存在否： $startupPath  ${startupPath.exists()}")
        if (startupPath.exists()) {
            startupItem.text = "取消开机启动"
            startupItem.actionCommand = "Disable"
        } else {
            startupItem.text = "加入开机启动"
            startupItem.actionCommand = "Enable"
        }
    }

    fun addStartup() {
        Utils.createShortcutStartup(Path(SystemUtils.jarRunPath))
        updateStartup()
    }

    @OptIn(ExperimentalPathApi::class)
    fun removeStartup() {
        startup.resolve("${Path(SystemUtils.jarRunPath).nameWithoutExtension}.lnk").deleteRecursively()
        updateStartup()
    }

    private fun readClassResource(filePath: String, run: (input: InputStream) -> Unit) {
        // 获取当前jar包所在路径
        val inputStream = Main::class.java.getResourceAsStream(filePath)
        if (inputStream == null) {
            logger.info("$filePath 文件没有找到")
        } else {
            run.invoke(inputStream)
        }
    }


}

fun alert(msg: String) {
    JOptionPane.showMessageDialog(null, msg)
}

fun toast(message: String) {
    // 显示通知
    // 注意：Windows系统下并不直接支持丰富的通知样式，通常会弹出一个简单的气泡提示
    Main.trayIcon?.displayMessage("通知", message, TrayIcon.MessageType.INFO)
}

fun main() {
    System.setProperty("runPath", SystemUtils.runPath.absolutePathString())
    SystemUtils.uniquePID()
    Main().start()
}